﻿namespace FFXIRC_CLIENT
{
    using System;
    using System.Collections;
    using System.Net;
    using System.Net.Sockets;
    using System.IO;
    using System.Threading;
    using System.Collections.Generic;
    using System.Collections.Specialized;
    using System.Text.RegularExpressions;

    enum ParseType : int
    {
        FFXI = 0,
        IRC = 1,
    }

    class LineParse
    {
        private ParseType _Type;
        private FFXI.eChatMode _ChatType;
        private Regex _Regex;
        private String _Action;

        public LineParse(ParseType pType, FFXI.eChatMode pChatType, String pRegex, String pAction)
        {
            _Type = pType;
            _ChatType = pChatType;
            _Regex = new Regex(pRegex);
            _Action = pAction;
        }

        public LineParse(ParseType pType, String pRegex, String pAction)
            : this(pType, FFXI.eChatMode.Unknown, pRegex, pAction)
        {
        }

        public ParseType Type
        {
            get
            {
                return _Type;
            }
        }

        public FFXI.eChatMode ChatType
        {
            get
            {
                return _ChatType;
            }
        }

        public Regex Regex
        {
            get
            {
                return _Regex;
            }
        }

        public String Action
        {
            get
            {
                return _Action;
            }
        }
    }


    class FFXI_to_IRC
    {
        Thread reader;
        Thread consoleReader;
        Thread writer;
        public List<LineParse> FFXI_PARSES = new List<LineParse>();
        public List<LineParse> IRC_PARSES = new List<LineParse>();

        public static Queue f2imessageQueue;

        public FFXI_to_IRC()
        {
            f2imessageQueue = Queue.Synchronized(new Queue());
            reader = new Thread(new ThreadStart(this.readFromFFXI));
            consoleReader = new Thread(new ThreadStart(this.readFromConsole));
            writer = new Thread(new ThreadStart(this.writeToIRC));
        }

        public void Start()
        {
            reader.Start();
            consoleReader.Start();
            writer.Start();
        }

        public void readFromFFXI()
        {
            bool loop = true;
            FFXI.FFACE.Chat.ChatLogEntry chatLine;
            while (loop)
            {
                if (!Program.parseChatLog)
                    Program.parseChatLogEvent.WaitOne();
                if (FFXI.FFACE.Chat.isNewLine())
                {
                    chatLine = FFXI.FFACE.Chat.GetLine(0);
                    ThreadPool.QueueUserWorkItem(new WaitCallback(parseChat), (object)chatLine); ;
                }
                else
                {
                    Thread.Sleep(100);
                }
                //loop = FFXI.FFACE.Main.FFXiIsOpen();
            }
        }

        public void readFromConsole()
        {
            String lastLine = "";

            while (FFXI.FFACE.Main.FFXiIsOpen())
            {
                String[] line = FFXI.Windower.MainFunctions.GetArgs();
                if (line.Length > 0)
                {

                    String parseLine = "";
                    foreach (String l in line)
                    {
                        parseLine = parseLine + l + " ";
                    }
                    if (lastLine != parseLine)
                    {
                        parseCommand(line);
                        lastLine = parseLine;
                    }
                    else
                    {
                        Thread.Sleep(10);
                    }
                }
            }
        }
        public void parseChat(object chatLine)
        {
            String line = ((FFXI.FFACE.Chat.ChatLogEntry)chatLine).LineText;
            FFXI.eChatMode messageType = ((FFXI.FFACE.Chat.ChatLogEntry)chatLine).LineType;
            foreach(LineParse lp in FFXI_PARSES)
            {
                if (lp.ChatType == messageType)
                {
                    Match LineMatch = Regex.Match(line,lp.Regex.ToString());
                    if (LineMatch.Success)
                    {
                        String res = LineMatch.Result(lp.Action);
                        parseCommand(res.Split(),false);
                    }
                }
            }
        }
        public void parseCommand(String[] args)
        {
            parseCommand(args, true);
        }
        public void parseCommand(String[] args, bool toEcho)
        {
            FFXI.Windower.MainFunctions.SendText("//unparsed");
            String toSend;
            String line = "";

            /* If there are no arguments, return right away */
            if (args.Length <= 0)
                return;
            String command = args[0].ToUpper();
#if DEBUG
            System.Console.Out.WriteLine(command);
#endif
            
            command = GetCommandType(command);
            if (command == "NONE")
                return;


            line = command;
            for (int i = 1; i < args.Length; i++)
            {
                line = line + " " + args[i];
            }
            args = line.Split();
            command = args[0];
            toSend = line;
            String echo = toSend;

            if (command == "IRCINPUT")
            {
                String ircinput = line.Substring(args[0].Length + 1);
                IRC_to_FFXI.i2fmessageQueue.Enqueue(ircinput);
                /*String prefix = ircinput.Split()[0];
                if(prefix.StartsWith("/"))
                {
                    ircinput = ircinput.Substring(prefix.Length+1);
                }
                else
                {
                    prefix = "";
                }
                int max_msg_len = 90;
                if (ircinput.Length > max_msg_len)
                {
                    while (ircinput.Length > max_msg_len)
                    {
                        int lastSpace = ircinput.Substring(0, max_msg_len).LastIndexOf(" ");
                        if (lastSpace > 1)
                        {
                            FFXI.Windower.MainFunctions.SendText(prefix + " " + ircinput.Substring(0, lastSpace));
                            ircinput = "*" + ircinput.Substring(lastSpace);
                        }
                        else
                        {
                            FFXI.Windower.MainFunctions.SendText(prefix + " " + ircinput.Substring(0, max_msg_len));
                            ircinput = "* " + ircinput.Substring(max_msg_len);
                        }
                        Thread.Sleep(1200);
                    }
                }
                if (ircinput.Length <= max_msg_len)
                {
                    FFXI.Windower.MainFunctions.SendText(prefix + " " + ircinput);
                }*/
                return;
            }
            if (command == "PRIVMSG")
            {
                if (args.Length < 3)
                {
                    return;
                }
                
                Match theMatch = Regex.Match(line, "PRIVMSG (?<chan>.*?) (?<message>.*)");
                echo = theMatch.Result(string.Concat("{", FFXIRC_CLIENT.IrcClient.myClient.Nickname, "@${chan}} ${message}"));
                toSend = theMatch.Result("PRIVMSG ${chan} :${message}");
            }
            else if (command == "PART")
            {
                if (args.Length >= 2)
                {
                    try
                    {
                        int chan_num = int.Parse(args[1]);
                        String chan_name = "";
                        String[] channels = new String[IrcClient.myClient.JoinedChannels.Count];
                        IrcClient.myClient.JoinedChannels.CopyTo(channels, 0);
                        chan_name = channels[chan_num];
                        toSend = args[0] + " " + chan_name + toSend.Substring(toSend.IndexOf(args[1]) + args[1].Length);
                        Match theMatch = Regex.Match(line, "PART (?<chan>.*?) (?<message>.*)");
                        toSend = theMatch.Result(string.Concat("PART ",chan_name," :${message}"));
                        echo = toSend;
                    }
                    catch { }
                }
                if (args.Length >= 3)
                {
                    Match theMatch = Regex.Match(line, "PART (?<chan>.*?) (?<message>.*)");
                    toSend = theMatch.Result("PART ${chan} :${message}");
                }
                
            }
            else if (command == "QUITIRC" || command == "DISCONNECT")
            {
                if (args.Length >= 2)
                {
                    toSend = "QUIT :" + toSend.Substring(args[0].Length + 1, toSend.Length - args[0].Length - 1);
                }
                else
                {
                    toSend = "QUIT";
                }
            }
            if(toEcho)
                IRC_to_FFXI.i2fmessageQueue.Enqueue(echo);
            if (command == "CHANNELS")
            {
                int i = 0;
                foreach (String s in IrcClient.myClient.JoinedChannels)
                {
                    if (s.Length < 1) continue;
                    IRC_to_FFXI.i2fmessageQueue.Enqueue(""+i+": "+s);
                    i++;
                }
            }
            else if (command == "LOGIN")
            {
                String name = FFXI.FFACE.Player.Name();
                String password = "";
                if (args.Length >= 3)
                {
                    password = args[2];
                }
                if (args.Length >= 2)
                {
                    name = args[1];
                }

                String[] nameList = { name, name + "_", "_" + name };
                FFXIRC_CLIENT.IrcClient.myClient.Login(nameList, "In-game FFXI player", 1, "FFXIRCclientV1.0", password);
            }
            else if (command == "LOADFILE")
            {
                if (args.Length > 1)
                {
                    StreamReader SR;
                    string s;
                    try
                    {
                        SR = File.OpenText(args[1]);
                        s = SR.ReadLine();
                        for (; s != null; s = SR.ReadLine())
                        {
                            string[] cmd_args = s.Split();
                            if (s.Trim().StartsWith("#"))
                            {
                                continue;
                            }
                            //else if (cmd_args[0].ToUpper() == "JOIN")
                            //{
                            //    FFXIRC_CLIENT.Program.identified.WaitOne();
                            //}
                            IrcClient.f2i.parseCommand(cmd_args);
                        }
                    }
                    catch(Exception e)
                    {
                        IRC_to_FFXI.i2fmessageQueue.Enqueue(e.Message);
                    }
                }
            }
            else if (command == "PARSECHATLOG")
            {
                if (args.Length > 1)
                {
                    if (args[1].ToUpper() == "ON")
                    {
                        Program.parseChatLog = true;
                        Program.parseChatLogEvent.Set();
                    }
                    else if (args[1].ToUpper() == "OFF")
                    {
                        Program.parseChatLog = false;
                        Program.parseChatLogEvent.Reset();
                    }
                    else
                    {
                        IRC_to_FFXI.i2fmessageQueue.Enqueue("Improper use: PARSECHATLOG <on|off>");
                    }
                }
                else
                {
                    IRC_to_FFXI.i2fmessageQueue.Enqueue("Improper use: PARSECHATLOG <on|off>");
                }
            }
            else if (command == "PARSECHATLINE")
            {
                if (args.Length >= 4)
                {
                    String extract = "(?<LineType>.*?) '(?<RegularExpression>.*?)' '(?<Action>.*?)'";
                    Match extractionMatch = Regex.Match(line.Substring(line.IndexOf(args[0]) + args[0].Length + 1), extract);
                    if (extractionMatch.Success)
                    {
                        String LineType = extractionMatch.Result("${LineType}");
                        String RegularExpression = extractionMatch.Result("${RegularExpression}");
                        String Action = extractionMatch.Result("${Action}");

                        FFXI.eChatMode Type;
                        Type = getLineType(LineType);

                        FFXI_PARSES.Add(new LineParse(ParseType.FFXI, Type, RegularExpression, Action));
                        IRC_to_FFXI.i2fmessageQueue.Enqueue("ChatLine parse successfully added.");
                    }
                    else
                    {
                        IRC_to_FFXI.i2fmessageQueue.Enqueue("Improper use: PARSECHATLINE <type> 'Regex' 'Windower Command'");
                    }
                }
                else if (args.Length == 2)
                {
                    if (args[1].ToUpper() == "LIST")
                    {
                        int i = 0;
                        foreach (LineParse lp in FFXI_PARSES)
                        {
                            IRC_to_FFXI.i2fmessageQueue.Enqueue(i + ": " + lp.ChatType + " '" + lp.Regex.ToString() + "' '" + lp.Action + "'");
                            i++;
                        }
                    }
                }
                else if (args.Length == 3)
                {
                    if (args[1].ToUpper() == "DELETE")
                    {
                        try
                        {
                            int index = int.Parse(args[2]);
                            FFXI_PARSES.RemoveAt(index);
                            IRC_to_FFXI.i2fmessageQueue.Enqueue("FFXI Parse index " + index + " successfully removed.");
                        }
                        catch
                        {
                            IRC_to_FFXI.i2fmessageQueue.Enqueue("Improper use: PARSECHATLINE DELETE <index>. Either the index you entered was not a number or it was out of range.");
                        }
                    }
                }
                else
                {
                    IRC_to_FFXI.i2fmessageQueue.Enqueue("Improper use: PARSECHATLINE {LIST,DELETE <index>, <type> 'Regex' 'Windower Command'}");
                }
            }
            else if (command == "PARSEIRCLINE")
            {
                if (args.Length == 2)
                {
                    if (args[1].ToUpper() == "LIST")
                    {
                        int i = 0;
                        foreach (LineParse lp in IRC_PARSES)
                        {
                            IRC_to_FFXI.i2fmessageQueue.Enqueue(i + ": " + lp.ChatType + " " + lp.Regex.ToString() + " " + lp.Action);
                            i++;
                        }
                    }
                }
                if (args.Length == 3)
                {
                    if (args[1].ToUpper() == "DELETE")
                    {
                        try
                        {
                            int index = int.Parse(args[2]);
                            IRC_PARSES.RemoveAt(index);
                            IRC_to_FFXI.i2fmessageQueue.Enqueue("IRC Parse index " + index + " successfully removed.");
                        }
                        catch
                        {
                            IRC_to_FFXI.i2fmessageQueue.Enqueue("Improper use: PARSEIRCLINE DELETE <index>. Either the index you entered was not a number or it was out of range.");
                        }
                    }
                }
                else if (args.Length >= 3)
                {
                    String extract = "'(?<RegularExpression>.*?)' '(?<Action>.*?)'";
                    Match extractionMatch = Regex.Match(line.Substring(line.IndexOf(args[0]) + args[0].Length + 1), extract);
                    if (extractionMatch.Success)
                    {
                        String RegularExpression = extractionMatch.Result("${RegularExpression}");
                        String Action = extractionMatch.Result("${Action}");

                        IRC_PARSES.Add(new LineParse(ParseType.IRC, RegularExpression, Action));
                        IRC_to_FFXI.i2fmessageQueue.Enqueue("IRCLine parse successfully added.");
                    }
                    else
                    {
                        IRC_to_FFXI.i2fmessageQueue.Enqueue("Improper use: PARSEIRCLINE 'Regex' 'Windower Command'");
                    }
                }
                else
                {
                    IRC_to_FFXI.i2fmessageQueue.Enqueue("Improper use: PARSEIRCLINE 'Regex' 'Windower Command'");
                }
            }
            else if (command == "CONNECT")
            {
                String address = "";
                int port = 6667;
                if (args.Length >= 2)
                {
                    address = args[1];
                }
                if (args.Length >= 3)
                {
                    try
                    {
                        port = int.Parse(args[2]);
                    }
                    catch
                    {
                    }
                }
                if (args.Length >= 2)
                {
                    try
                    {
                        FFXIRC_CLIENT.IrcClient.myClient.Connect(address, port);
                    }
                    catch (Exception e)
                    {
                        IRC_to_FFXI.i2fmessageQueue.Enqueue(e.Message);
                    }
                }
            }
            else if (command == "RECONNECT")
            {
                bool login = true;
                bool channels = true;
                if (args.Length >= 2)
                {
                    login = args[1] == "1" ? true : false;
                }
                if (args.Length >= 3)
                {
                    channels = args[2] == "1" ? true : false;
                }
                FFXIRC_CLIENT.IrcClient.myClient.Reconnect(login,channels);
            }
            else if (command == "HELP")
            {
                if (args.Length == 1)
                {
                    IRC_to_FFXI.i2fmessageQueue.Enqueue("[ Help Commands ]");
                    foreach (string cmd in Keywords.validcmds)
                    {
                        IRC_to_FFXI.i2fmessageQueue.Enqueue(cmd);
                    }
                }
                else if (args.Length == 2)
                {
                    args[1] = args[1].ToUpper();
                    if (Keywords.validcmds.Contains(args[1]))
                    {
                        if (args[1] == "HELP")
                        {
                            IRC_to_FFXI.i2fmessageQueue.Enqueue("Usage: HELP [cmd]");
                            IRC_to_FFXI.i2fmessageQueue.Enqueue("Purpose: Obtain information on usage and purpose of commands.");
                        }
                        else if (args[1] == "AWAY")
                        {
                            IRC_to_FFXI.i2fmessageQueue.Enqueue("Usage: AWAY [<message>]");
                            IRC_to_FFXI.i2fmessageQueue.Enqueue("Purpose: Set an away message, or use no message to return from away.");
                        }
                        else if (args[1] == "CONNECT")
                        {
                            IRC_to_FFXI.i2fmessageQueue.Enqueue("Usage: CONNECT <address> [<port>]");
                            IRC_to_FFXI.i2fmessageQueue.Enqueue("Purpose: Connect to an IRC server. If no port is specified 6667 will be used");
                        }
                        else if (args[1] == "DISCONNECT")
                        {
                            IRC_to_FFXI.i2fmessageQueue.Enqueue("Usage: DISCONNECT [<message>]");
                            IRC_to_FFXI.i2fmessageQueue.Enqueue("Purpose: Disconnect from the currently connected IRC server. A quit message is optional.");
                        }
                        else if (args[1] == "INVITE")
                        {
                            IRC_to_FFXI.i2fmessageQueue.Enqueue("Usage: INVITE <chan> <user>");
                            IRC_to_FFXI.i2fmessageQueue.Enqueue("Purpose: Invite a user to join a channel you are currently in.");
                        }
                        else if (args[1] == "JOIN")
                        {
                            IRC_to_FFXI.i2fmessageQueue.Enqueue("Usage: JOIN <chan>");
                            IRC_to_FFXI.i2fmessageQueue.Enqueue("Purpose: Join a channel.");
                        }
                        else if (args[1] == "KICK")
                        {
                            IRC_to_FFXI.i2fmessageQueue.Enqueue("Usage: <chan> <user>");
                            IRC_to_FFXI.i2fmessageQueue.Enqueue("Purpose: Remove a user from a channel. You must be a channel operator to do this.");
                        }
                        else if (args[1] == "LOADFILE")
                        {
                            IRC_to_FFXI.i2fmessageQueue.Enqueue("Usage: LOADFILE <filepath>");
                            IRC_to_FFXI.i2fmessageQueue.Enqueue("Purpose: Load a config file to execute commands.");
                        }
                        else if (args[1] == "LOGIN")
                        {
                            IRC_to_FFXI.i2fmessageQueue.Enqueue("Usage: LOGIN [<name> [<password>]]");
                            IRC_to_FFXI.i2fmessageQueue.Enqueue("Purpose: Login to IRC.");
                        }
                        else if (args[1] == "MODE")
                        {
                            IRC_to_FFXI.i2fmessageQueue.Enqueue("Usage: MODE channel: <chan|user> <+|-><A-Za-z> [<user>] user: <user> <+|-><A-Za-z>");
                            IRC_to_FFXI.i2fmessageQueue.Enqueue("Purpose: Set or unset a channel or user mode");
                            IRC_to_FFXI.i2fmessageQueue.Enqueue("Channel Modes: o - operator, p - private, s - secret, i - invite only,");
                            IRC_to_FFXI.i2fmessageQueue.Enqueue("* t - topic settable by channel operater only,");
                            IRC_to_FFXI.i2fmessageQueue.Enqueue("* n - no messages to channel from cliens on the outside,");
                            IRC_to_FFXI.i2fmessageQueue.Enqueue("* m - moderated channel, l - set user limit, b - set ban mask,");
                            IRC_to_FFXI.i2fmessageQueue.Enqueue("* v - give/tage the ability to speak on a moderated channel,");
                            IRC_to_FFXI.i2fmessageQueue.Enqueue("* k - set a channel key (password).");
                            IRC_to_FFXI.i2fmessageQueue.Enqueue("User Modes: i - invisible, s - receive server notices,");
                            IRC_to_FFXI.i2fmessageQueue.Enqueue("* w - user receives wallops, o - operator.");
                        }
                        else if (args[1] == "NAMES")
                        {
                            IRC_to_FFXI.i2fmessageQueue.Enqueue("Usage: NAMES <chan>");
                            IRC_to_FFXI.i2fmessageQueue.Enqueue("Purpose: List the names of the users currently in a channel.");
                        }
                        else if (args[1] == "NICK")
                        {
                            IRC_to_FFXI.i2fmessageQueue.Enqueue("Usage: NICK <name>");
                            IRC_to_FFXI.i2fmessageQueue.Enqueue("Purpose: Change your nickname.");
                        }
                        else if (args[1] == "NOTICE")
                        {
                            IRC_to_FFXI.i2fmessageQueue.Enqueue("Usage: NOTICE <user|chan> <message>");
                            IRC_to_FFXI.i2fmessageQueue.Enqueue("Purpose: Send a notice to a user or a channel.");
                        }
                        else if (args[1] == "PARSECHATLOG")
                        {
                            IRC_to_FFXI.i2fmessageQueue.Enqueue("Usage: PARSECHATLOG <on|off>");
                            IRC_to_FFXI.i2fmessageQueue.Enqueue("Purpose: Turn on/off chatlog parsing.");
                        }
                        else if (args[1] == "PARSECHATLINE")
                        {
                            IRC_to_FFXI.i2fmessageQueue.Enqueue("Usage: PARSECHATLINE {LIST, DELETE <index>, <type> 'Regex' 'FFXIRC Command'}");
                            IRC_to_FFXI.i2fmessageQueue.Enqueue("Purpose: Set a chatlog message matching a regular expression to automatically execute a windower command.");
                        }
                        else if (args[1] == "PARSEIRCLINE")
                        {
                            IRC_to_FFXI.i2fmessageQueue.Enqueue("Usage: PARSEIRCLINE {LIST, DELETE <index>, 'Regex' 'FFXIRC Command'}");
                            IRC_to_FFXI.i2fmessageQueue.Enqueue("Purpose: Set an IRC message matching a regular expression to automatically execute a windower command. Note: You should be familiar with IRC message format before attempting to use this.");
                        }
                        else if (args[1] == "PART")
                        {
                            IRC_to_FFXI.i2fmessageQueue.Enqueue("Usage: PART <chan> [<message>]");
                            IRC_to_FFXI.i2fmessageQueue.Enqueue("Purpose: Leave the specified channel (using a number works), with an optional message.");
                        }
                        else if (args[1] == "PING")
                        {
                            IRC_to_FFXI.i2fmessageQueue.Enqueue("Usage: PING <user>");
                            IRC_to_FFXI.i2fmessageQueue.Enqueue("Purpose: Asks how much lag a user (or the server if no user specified) has.");
                        }
                        else if (args[1] == "PONG")
                        {
                            IRC_to_FFXI.i2fmessageQueue.Enqueue("Usage: PONG <user>");
                            IRC_to_FFXI.i2fmessageQueue.Enqueue("Purpose: Reply to a ping.");
                        }
                        else if (args[1] == "PRIVMSG" || args[1] == "PM" || args[1] == "MSG")
                        {
                            IRC_to_FFXI.i2fmessageQueue.Enqueue("Usage: PRIVMSG <user|chan> <message>");
                            IRC_to_FFXI.i2fmessageQueue.Enqueue("Purpose: Send a private message to a user or a channel (this is how you talk in IRC).");
                        }
                        else if (args[1] == "QUITIRC")
                        {
                            IRC_to_FFXI.i2fmessageQueue.Enqueue("Usage: QUITIRC [<message>]");
                            IRC_to_FFXI.i2fmessageQueue.Enqueue("Purpose: Disconnect from the IRC server, and close the program. A quit message is optional.");
                        }
                        else if (args[1] == "RECONNECT")
                        {
                            IRC_to_FFXI.i2fmessageQueue.Enqueue("Usage: RESCONNECT [<Login:0|1> [<Channels:0|1>]]");
                            IRC_to_FFXI.i2fmessageQueue.Enqueue("Purpose: Resconnect to the currently connected IRC server. You can relogin and rejoin your channels with the optional arguments.");
                        }
                        else if (args[1] == "TOPIC")
                        {
                            IRC_to_FFXI.i2fmessageQueue.Enqueue("Usage: TOPIC [<new topic>]");
                            IRC_to_FFXI.i2fmessageQueue.Enqueue("Purpose: View or change the channel topic.");
                        }
                    }
                    else
                    {
                        IRC_to_FFXI.i2fmessageQueue.Enqueue("Unknown command");
                    }
                }
                else
                {
                    IRC_to_FFXI.i2fmessageQueue.Enqueue("Improper use: HELP [cmd]");
                }
            }
            else
            {
                f2imessageQueue.Enqueue(toSend);
            }
            if (command == "QUITIRC")
            {
                Thread.Sleep(1000);
                Environment.Exit(0);
            }
            

        }

        public static FFXI.eChatMode getLineType(String LineType)
        {
            FFXI.eChatMode Type = FFXI.eChatMode.Unknown;
            LineType = LineType.ToUpper();
            try
            {
                Type = (FFXI.eChatMode)int.Parse(LineType);
            }
            catch
            {
                if (LineType == "CaughtOnHook".ToUpper())
                {
                    Type = FFXI.eChatMode.CaughtOnHook;
                }
                else if (LineType == "CommandError".ToUpper())
                {
                    Type = FFXI.eChatMode.CommandError;
                }
                else if (LineType == "DropRipCap".ToUpper())
                {
                    Type = FFXI.eChatMode.DropRipCap;
                }
                else if (LineType == "Echo".ToUpper())
                {
                    Type = FFXI.eChatMode.Echo;
                }
                else if (LineType == "EffectWearOff".ToUpper())
                {
                    Type = FFXI.eChatMode.EffectWearOff;
                }
                else if (LineType == "Emote1".ToUpper())
                {
                    Type = FFXI.eChatMode.Emote1;
                }
                else if (LineType == "Emote2".ToUpper())
                {
                    Type = FFXI.eChatMode.Emote2;
                }
                else if (LineType == "FishResult".ToUpper())
                {
                    Type = FFXI.eChatMode.FishResult;
                }
                else if (LineType == "ItemSold".ToUpper())
                {
                    Type = FFXI.eChatMode.ItemSold;
                }
                else if (LineType == "PlayerDefeats".ToUpper())
                {
                    Type = FFXI.eChatMode.PlayerDefeats;
                }
                else if (LineType == "PlayerReadiesMove".ToUpper())
                {
                    Type = FFXI.eChatMode.PlayerReadiesMove;
                }
                else if (LineType == "PlayersBadCast".ToUpper())
                {
                    Type = FFXI.eChatMode.PlayersBadCast;
                }
                else if (LineType == "PlayerStartCasting".ToUpper())
                {
                    Type = FFXI.eChatMode.PlayerStartCasting;
                }
                else if (LineType == "PlayerUsesJobAbility".ToUpper())
                {
                    Type = FFXI.eChatMode.PlayerUsesJobAbility;
                }
                else if (LineType == "PlayerzFightLog".ToUpper())
                {
                    Type = FFXI.eChatMode.PlayerzFightLog;
                }
                else if (LineType == "RcvdLinkShell".ToUpper())
                {
                    Type = FFXI.eChatMode.RcvdLinkShell;
                }
                else if (LineType == "RcvdParty".ToUpper())
                {
                    Type = FFXI.eChatMode.RcvdParty;
                }
                else if (LineType == "RcvdSay".ToUpper())
                {
                    Type = FFXI.eChatMode.RcvdSay;
                }
                else if (LineType == "RcvdShout".ToUpper())
                {
                    Type = FFXI.eChatMode.RcvdShout;
                }
                else if (LineType == "RcvdTell".ToUpper())
                {
                    Type = FFXI.eChatMode.RcvdTell;
                }
                else if (LineType == "RegConquest".ToUpper())
                {
                    Type = FFXI.eChatMode.RegConquest;
                }
                else if (LineType == "SentLinkShell".ToUpper())
                {
                    Type = FFXI.eChatMode.SentLinkShell;
                }
                else if (LineType == "SentParty".ToUpper())
                {
                    Type = FFXI.eChatMode.SentParty;
                }
                else if (LineType == "SentSay".ToUpper())
                {
                    Type = FFXI.eChatMode.SentSay;
                }
                else if (LineType == "SentShout".ToUpper())
                {
                    Type = FFXI.eChatMode.SentShout;
                }
                else if (LineType == "SentTell".ToUpper())
                {
                    Type = FFXI.eChatMode.SentTell;
                }
                else if (LineType == "ServerNotice".ToUpper())
                {
                    Type = FFXI.eChatMode.ServerNotice;
                }
                else if (LineType == "SkillBoost".ToUpper())
                {
                    Type = FFXI.eChatMode.SkillBoost;
                }
                else if (LineType == "SomeoneDefeats".ToUpper())
                {
                    Type = FFXI.eChatMode.SomeoneDefeats;
                }
                else if (LineType == "SynthResult".ToUpper())
                {
                    Type = FFXI.eChatMode.SynthResult;
                }
                else if (LineType == "TargetFightLog".ToUpper())
                {
                    Type = FFXI.eChatMode.TargetFightLog;
                }
                else if (LineType == "TargetMisses".ToUpper())
                {
                    Type = FFXI.eChatMode.TargetMisses;
                }
                else if (LineType == "TargetReadiesMove".ToUpper())
                {
                    Type = FFXI.eChatMode.TargetReadiesMove;
                }
                else if (LineType == "TargetUsesJobAbility".ToUpper())
                {
                    Type = FFXI.eChatMode.TargetUsesJobAbility;
                }
                else if (LineType == "TellNotRcvd".ToUpper())
                {
                    Type = FFXI.eChatMode.TellNotRcvd;
                }
                else if (LineType == "Unknown".ToUpper())
                {
                    Type = FFXI.eChatMode.Unknown;
                }
            }
            return Type;
        }

        public String GetCommandType(String command)
        {
            if (command == "PRIVMSG" || command == "PM" || command == "MSG")
                return "PRIVMSG";
            if (command == "IRCINPUT")
                return "IRCINPUT";
            if (command == "JOIN")
                return "JOIN";
            if (command == "KICK")
                return "KICK";
            if (command == "NICK")
                return "NICK";
            if (command == "NAMES")
                return "NAMES";
            if (command == "PART")
                return "PART";
            if (command == "TOPIC")
                return "TOPIC";
            if (command == "MODE")
                return "MODE";
            if (command == "INVITE")
                return "INVITE";
            if (command == "WHO")
                return "WHO";
            if (command == "WHOIS")
                return "WHOIS";
            if (command == "TOPIC")
                return "TOPIC";
            if (command == "TIME")
                return "TIME";
            if (command == "PING")
                return "PING";
            if (command == "CHANNELS" || command == "CHANS")
                return "CHANNELS";
            if (command == "PARSECHATLOG")
                return "PARSECHATLOG";
            if (command == "PARSECHATLINE")
                return "PARSECHATLINE";
            if (command == "PARSEIRCLINE")
                return "PARSEIRCLINE";
            if (command == "LOADFILE")
                return "LOADFILE";
            if (command == "COMMANDS" || command == "HELP")
                return "HELP";
            if (command == "QUITIRC")
                return "QUITIRC";
            if (command == "CONNECT")
                return "CONNECT";
            if (command == "DISCONNECT")
                return "DISCONNECT";
            if (command == "LOGIN")
                return "LOGIN";
            if (command == "LOADFILE")
                return "LOADFILE";
            if (command == "RECONNECT")
                return "RECONNECT";
            try
            {
                String[] theArgs = command.Split(',');
                String targets = "";
                foreach (String arg in theArgs)
                {
                    int chan_num = int.Parse(command);
                    String chan_name = "";
                    String[] channels = new String[IrcClient.myClient.JoinedChannels.Count];
                    IrcClient.myClient.JoinedChannels.CopyTo(channels, 0);
                    chan_name = channels[chan_num];
                    if (theArgs.Length == 1)
                        targets = chan_name;
                    else
                        targets = targets + "," + chan_name;
                }
                return "PRIVMSG " + targets;
            }
            catch { }
            return "NONE";
        }

        public void writeToIRC()
        {
            while (true)
            {
                if (f2imessageQueue.Count > 0)
                {
                    String toSend = (String)f2imessageQueue.Dequeue();
                    //Console.Out.WriteLine("Sending " + toSend + " to IRC");
                    FFXIRC_CLIENT.IrcClient.myClient.WriteLine(toSend);
                }
                else
                {
                    Thread.Sleep(1000);
                }
            }
        }
    }
}